package com.yy.jhl.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;

import com.yy.jhl.R;


/**
 * Created by chenjiawei on 15/12/9.
 */
public class SwipeLayout extends LinearLayout {

    private static final String TAG = "SwipeLayout";

    private Context mContext;

    private LinearLayout mContentView;

    private RelativeLayout mRightView;

    private Scroller mScroller;

    private OnSlideListener mOnSlideListener;

    private int mHolderWidth = 120;

    private int mLastX = 0;

    private int mLastY = 0;

    private static final int TAN = 2;

    private int mSlideState = 0;
    public boolean isScroll = true;

    public void setScroll(boolean scroll) {
        isScroll = scroll;
    }

    public interface OnSlideListener {
        int SLIDE_STATUS_OFF = 0;
        int SLIDE_STATUS_START_SCROLL = 1;
        int SLIDE_STATUS_ON = 2;
        void onSlide(View view, int status);
    }

    public SwipeLayout(Context context) {
        super(context);
        initView();
    }

    public SwipeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        mContext = getContext();
        mScroller = new Scroller(mContext);
        setOrientation(LinearLayout.HORIZONTAL);
        View.inflate(mContext, R.layout.container_swipelayout, this);
        mContentView = (LinearLayout) findViewById(R.id.view_content);
        mRightView = (RelativeLayout)findViewById(R.id.view_right);
        mHolderWidth = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()
                        .getDisplayMetrics()));
    }
    //将View加入到mContentView中
    public void setContentView(View view) {
        mContentView.addView(view);
    }

    //将View加入到mRightView中
    public void setRightView(View v) {
        mRightView.addView(v);
    }

    public void setOnSlideListener(OnSlideListener onSlideListener) {
        mOnSlideListener = onSlideListener;
    }

    //将当前状态设置为关闭
    public void shrink() {
        if (getScrollX() != 0) {
            this.smoothScrollTo(0, 0);
        }
    }
    //如果其子View存在消耗点击事件的View，那么SwipeLayout的onTouchEvent不会被执行，
    // 因为在ACTION_MOVE的时候返回true，执行其onTouchEvent方法
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:

                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }

                if (mOnSlideListener != null) {
                    mOnSlideListener.onSlide(this,
                            OnSlideListener.SLIDE_STATUS_START_SCROLL);
                    mSlideState = OnSlideListener.SLIDE_STATUS_START_SCROLL;
                }
                //这里需要记录mLastX，mLastY的值，不然当SwipeLayout已经处于开启状态时，
                // 用于再次滑动SwipeLayout时，会先立即复原到关闭状态，用户体验不太好
                mLastX = (int)ev.getX();
                mLastY = (int)ev.getY();
                return false;
            case MotionEvent.ACTION_MOVE:
                return true;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        int scrollX = getScrollX();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {

                break;
            }
            case MotionEvent.ACTION_MOVE: {
                if (!isScroll)return false;
                //如果SwipeLayout是在譬如ScrollView、ListView这种可以上下滑动的View中
                //那么当用户的手指滑出SwipeLayout的边界，那么将会触发器ACTION_CANCEL事件
                //如果此情形发生，那么SwipeLayout将会处于停止状态，无法复原。
                //增加下面这句代码，就是告诉父控件，不要cancel我的事件，我的事件我继续处理。
                getParent().requestDisallowInterceptTouchEvent(true);
                int deltaX = x - mLastX;
                int deltaY = y - mLastY;
                //这里作用是来比较X、Y轴的滑动距离，如果X轴的滑动距离小于两倍的Y轴滑动距离，则不执行SwipeLayout的滑动事件
                if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {
                    break;
                }

                int newScrollX = scrollX - deltaX;
                if (deltaX != 0) {
                    //最小的滑动距离为0
                    if (newScrollX < 0) {
                        newScrollX = 0;
                    }
                    //最大的滑动距离就是mRightView的宽度
                    else if (newScrollX > mHolderWidth) {
                        newScrollX = mHolderWidth;
                    }
                    this.scrollTo(newScrollX, 0);
                }
                break;
            }
            case MotionEvent.ACTION_UP: {
                int newScrollX = 0;
                //如果已滑动的距离满足下面条件，则SwipeLayout直接滑动到最大距离，不然滑动到最小距离0
                if (scrollX - mHolderWidth * 0.75 > 0) {
                    newScrollX = mHolderWidth;
                }
                this.smoothScrollTo(newScrollX, 0);
                if (mOnSlideListener != null) {
                    if (newScrollX == 0){
                        mOnSlideListener.onSlide(this, OnSlideListener.SLIDE_STATUS_OFF);
                        mSlideState = OnSlideListener.SLIDE_STATUS_OFF;
                    }
                    else {
                        mOnSlideListener.onSlide(this, OnSlideListener.SLIDE_STATUS_ON);
                        mSlideState = OnSlideListener.SLIDE_STATUS_ON;
                    }
                    return false;
                }
            }
            default:
                break;
        }
        mLastX = x;
        mLastY = y;
        return true;
    }
    //获取当前SwipeLayout的滑动状态
    public int getSideState(){
        return mSlideState;
    }

    private void smoothScrollTo(int destX, int destY) {
        // 缓慢滚动到指定位置
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
        }
    }

}